feat(showcase): make v16 approvals demonstrable out of the box#3364
Merged
Conversation
The v16 marquee approval features (M-of-N quorum + finance∧legal 会签, server-computed progress, metadata-driven decision actions, ?request= deep links) could not be exercised in the showcase on a fresh boot: - the approval flows route to `finance`/`legal` positions that were never defined (only manager/exec/... existed) — a dangling reference that made the flows unroutable even when triggered manually; - no user held any approver position (assignments are runtime admin actions, users can't be seeded), so every request resolved to an empty slate; - the seed loader suppresses record-change flows (#2661), so seeding a `sent` invoice never opened a request; and `sys_approval_request` is engine-owned (ADR-0103), so a request can't be inserted through the data API either. Fix, mirroring `bind-position-sets.ts` (imperative, on `kernel:bootstrapped`): - define the `finance` + `legal` approval-routing positions; - assign the dev-seeded admin to manager/finance/legal (`sys_user_position`) so they resolve as an approver and can act in the inbox — org resolved from `sys_member` (the admin's `sys_user.organization_id` is null), so the org-scoped approver resolution + `getRequest` both match; - provision a phone-based demo user so the "phone sign-in surfaces" show a real number in the All Users list + detail; - seed a high-value (`$8,900`) submitted `EXP-DEMO` report and launch the Invoice Dual Sign-off (会签) and High-Value Committee Quorum (2-of-3) flows through the real automation engine, so two genuine, resumable pending requests land in the inbox on first boot; - add a "Submit for Sign-off" record action on invoices so the flow can be re-triggered on demand from the UI. Idempotent throughout (persistent DB keeps the rows; `openNodeRequest` rejects duplicate pending requests, which we swallow). Verified: on a fresh `objectstack dev --seed-admin`, the Approval Center shows both requests (待我审批 = 2) with the server-computed progress ("Approvals — 0 of 1", the 2→1 quorum clamp) and the metadata-driven Approve/Reject/Reassign/Send-back/ Request-info bar. `os validate` + `tsc --noEmit` pass. Found during the #3358 v16.0 verification sweep. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
The v16 approval-demo change added `finance` + `legal` positions to positions.ts (7 → 9), but seed.test.ts still asserted 7, failing Test Core. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
os-zhuang
added a commit
that referenced
this pull request
Jul 21, 2026
…ation (#3393) The v16 sweep (#3358 §4) couldn't exercise three shipped features because the showcase never demonstrated them out of the box — a gap `coverage.ts` doesn't catch (it tracks metadata KINDS, not sub-features like action-param widget types or list pagination). Fill them: - **Action-param widget gallery** (`ActionParamGalleryAction` on Field Zoo): one inline param of every non-trivial type so the ADR-0059 `ActionParamDialog` renders each real field widget — richtext editor, color picker, date picker, select, number, the AutoNumber widget for an `autonumber` param, and the⚠️ `image`/`file` uploads (multiple/accept/maxSize + the upload guard). No showcase action declared `params` before, so these dialogs were undemonstrated. - **Related-list pagination**: 24 bulk prospects under one account (Northwind) so its Account → Contacts related list exceeds a page and demonstrates server-side `$top`/`$skip` windowing (objectui#2711) on a fresh boot. - Record the sub-feature demonstration in the `action` coverage entry. Verified in the running app: the ParamDialog renders richtext/select/date/color/ autonumber widgets + image/file upload zones (not text boxes); the Northwind Contacts related list holds 26 rows but fetches `?top=5` (windowed, not load-all). `os validate` (9 Actions) + `tsc --noEmit` pass. Follow-up to #3364, from the #3358 sweep §4. Co-authored-by: Jack Zhuang <277994282+os-zhuang@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
os-zhuang
added a commit
that referenced
this pull request
Jul 22, 2026
The v16 sweep (#3358 §4 "Record History tab") couldn't exercise the tab because no showcase object opted into it: the console gates the History tab on object-level `enable.trackHistory` (RecordDetailView) — audit *capture* is always on, but the *tab* is opt-in — and the showcase only set `trackHistory` at the FIELD level (industry/status), which just selects which diffs are summarized. So the tab never rendered anywhere and #2691/#3293 (display-value diffs, computed-field exclusion) were undemonstrated. Set `enable: { trackHistory: true }` on Account (which already declares field-level `trackHistory` on `industry`/`status` for clean diffs). Verified in the running app: the Account detail now shows a **历史 / History** tab; after editing `industry`, it renders "Dev Admin · UPDATE · 行业: Retail → Technology" — field label + select **display values** (not raw stored codes/ids), no phantom value→null rows. `os validate` + `tsc --noEmit` pass. Follow-up to #3364 / #3393, from the #3358 sweep §4. Co-authored-by: Jack Zhuang <277994282+os-zhuang@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
During the #3358 v16.0 verification sweep, the marquee approval features weren't demonstrable in the showcase out of the box — the checklist assumes "seeds make most features demonstrable," but for §1 they didn't. Root causes:
showcase_invoice_signoffandshowcase_committee_quorumflows route tofinance/legalpositions that were never defined (positions.tsonly had manager/exec/auditor/ops/…). So the flows were unroutable even if triggered manually.sys_approval_requestis engine-owned (ADR-0103, get/list only), so nothing seeded a pending request.What
Mirrors the existing
bind-position-sets.tspattern (imperative, onkernel:bootstrapped):finance+legalpositions (positions.ts, now 9 positions).seed-approval-demo.ts(new): assigns the dev admin tomanager/finance/legal(sys_user_position), provisions a phone-based demo user, and launches both signoff flows through the real automation engine so two genuine, resumable pending requests land in the inbox on first boot.sys_member(the admin'ssys_user.organization_idis null) and threaded into both the position rows and the requests — otherwise the org-scoped approver resolution andgetRequest(inbox drawer) silently return nothing.execute()evaluates the start-node condition and reads the target object fromcontext.object, so the launch suppliesprevious(for theprevious.status != "sent"gate) andobject+organizationId.EXP-DEMOreport ($8,900, submitted) for the 2-of-3 quorum flow.Idempotent throughout (persistent DB keeps rows; duplicate-pending requests are rejected and swallowed). No changeset —
@objectstack/example-showcaseis private.Verified
Fresh
objectstack dev --ui --seed-admin:?request=<id>deep-links open the drawer directly.os validate✓ (9 Positions, 8 Actions) andtsc --noEmit✓.Known limitation
Because users can't be seeded, the admin holds all three approver positions, so the three approver slots all resolve to "Dev Admin" and the quorum collapses to 1 distinct approver. The decision mechanics (quorum tally, progress, actions, deep links) are fully exercised; a multi-user deployment would show distinct approvers.
🤖 Generated with Claude Code